/*
 * GuildServer.h
 *
 *  Created on: 2014. 7. 28.
 *      Author: mega
 */

#ifndef GUILDSERVER_H_
#define GUILDSERVER_H_

#include "Session.h"
#include <Dispatcher/Timer.h>
#include "../../../protocol/Guild.h"

namespace ProjectZ { namespace NProxy {

class GuildServer : public Session::IOwner, public::Dispatcher::Timer::IObserver
{
public:
	class Msg
	{
	public:
		static void OnOpenAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		static void OnCloseAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);

		static void OnMyGuildInfoAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		//static void OnLogoutGuildMemberAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		static void OnGuildInfoAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		static void OnGuildMemberAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		static void OnCreateGuildAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		static void OnJoinGuildAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		static void OnSearchGuildAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		static void OnGuildListAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		static void OnLeaveGuildAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		static void OnKickoutGuildMemberAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		static void OnGuildBuffGachyaAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		static void OnUpdateGuildJoinPasswordAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		static void OnUpdateGuildNoticeAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		static void OnUpdateGuildNoticeTextAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		static void OnUpdateGuildLevelAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		static void OnGuildCoolDownAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		static void OnSendGuildMailCheckAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		static void OnChatAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
		static void OnRecoverGuildAck(Dispatcher::Session * pSession, ::Network::Packet * pPacket);
	};

public:
	class State : public ::Dispatcher::NSession::State
	{
	public:
		State()
		{
			AddCommand(GuildOpenAck::MSG_ID, Msg::OnOpenAck);
			AddCommand(GuildCloseAck::MSG_ID, Msg::OnCloseAck);


			AddCommand(MyGuildInfoAck::MSG_ID, Msg::OnMyGuildInfoAck);
			//AddCommand(LogoutGuildMemberSyn::MSG_ID, Msg::OnLogoutGuildMemberAck);
			AddCommand(GuildInfoAck::MSG_ID, Msg::OnGuildInfoAck);
			AddCommand(GuildMemberAck::MSG_ID, Msg::OnGuildMemberAck);
			AddCommand(CreateGuildAck::MSG_ID, Msg::OnCreateGuildAck);
			AddCommand(JoinGuildAck::MSG_ID, Msg::OnJoinGuildAck);
			AddCommand(SearchGuildAck::MSG_ID, Msg::OnSearchGuildAck);
			//AddCommand(UpdateGuildLevelAck::MSG_ID, Msg::OnLevelUpGuildAck);
			AddCommand(GuildListAck::MSG_ID, Msg::OnGuildListAck);

			AddCommand(LeaveGuildAck::MSG_ID, Msg::OnLeaveGuildAck);
			AddCommand(KickoutGuildMemberAck::MSG_ID, Msg::OnKickoutGuildMemberAck);
			AddCommand(GuildBuffGachyaAck::MSG_ID, Msg::OnGuildBuffGachyaAck);
			AddCommand(UpdateGuildJoinPasswordAck::MSG_ID, Msg::OnUpdateGuildJoinPasswordAck);
			AddCommand(UpdateGuildNoticeAck::MSG_ID, Msg::OnUpdateGuildNoticeAck);
			AddCommand(UpdateGuildNoticeTextAck::MSG_ID, Msg::OnUpdateGuildNoticeTextAck);
			AddCommand(SendGuildMailCheckAck::MSG_ID, Msg::OnSendGuildMailCheckAck);
			AddCommand(UpdateGuildLevelAck::MSG_ID, Msg::OnUpdateGuildLevelAck);
			AddCommand(GuildCoolDownAck::MSG_ID, Msg::OnGuildCoolDownAck);
			AddCommand(BroadcastGuildChatAck::MSG_ID, Msg::OnChatAck);
			AddCommand(RecoverGuildAck::MSG_ID, Msg::OnRecoverGuildAck);
		}
	};

public:
	GuildServer();
	virtual ~GuildServer();

	bool	Connect(int idx, std::string ip, int port);
	void	OnDisconnect();
	virtual bool OnTime(int id, void* param);

	template<class T> void SendMessage(const T& msg)
	{
		if (false == _bConnect)
			return;

		::Network::Packet* pPacket = ::Network::GETPACKETPOOL()->SEND_NEW();
		char* pBuf = pPacket->GetOffsetPtr();
		if(false == msg.Store(&pBuf))
		{
			::Network::GETPACKETPOOL()->SEND_DEL(pPacket);
			return;
		}
		pPacket->SetLen(msg.Size());
		pPacket->MakePacketNoTail(T::MSG_ID);

		_pSession->SendPacket(pPacket, true);
	}

	int		GetIdx() { return _idx; }
	bool	IsConnect() { return _bConnect; }

private:
	void	setTime();

private:
	Session * _pSession;
	int _idx;
	bool _bConnect;
	::Network::Session::Info _clsInfo;
};

} /* namespace NProxy */ } /* namespace ProjectZ */

#endif /* GUILDSERVER_H_ */
